/**
* @brief 统一驱动: GPIO 驱动的开关
 * @author 张勇 41204@qq.com
 * @date 2022-04
*/

#pragma once

#include "mcu.h"
#include "unios.h"

/// 开关状态
typedef enum {
	UNIDRV_SWITCH_OFF = 0,	// 关
	UNIDRV_SWITCH_ON,		// 开
	UNIDRV_SWITCH_TOGGLE,	// 反转
	UNIDRV_SWITCH_BLINK,	// 闪烁
	UNIDRV_SWITCH_BREATH,	// 呼吸
	UNIDRV_SWITCH_MAX
} unidrv_switch_state_t;

/// 开关类(如LED/继电器) 驱动
typedef struct {
	func_gpio_switch_t funcSwitch;	///< GPIO 驱动函数
	unidrv_switch_state_t state;
    unios_task_t offTaskId;			///< 单次闪烁关闭任务ID
    unios_task_t blinkTaskId;		///< 闪烁任务ID
    uint32_t blinkExOnTime;    		///< 闪烁亮的时间
} unidrv_switch_t;

/// @brief 初始化
/// @param dev 驱动数据结构指针
/// @param funcSwitch 开关驱动函数
std_err_t unidrv_switch_init(unidrv_switch_t* dev, func_gpio_switch_t funcSwitch);

/// @brief 开关到指定状态
/// @param state: 0-OFF; 1-ON; 0xFF-REVERSE;
/// @return 状态是否变化了
bool unidrv_switch_to(unidrv_switch_t* dev, unidrv_switch_state_t state, uint32_t keepTime1, uint32_t keepTime2, uint8_t flashTimes);

/// @brief 亮
inline static bool unidrv_switch_on(unidrv_switch_t* dev) { return unidrv_switch_to(dev, UNIDRV_SWITCH_ON, 0, 0, 0); }
/// @brief 灭
inline static bool unidrv_switch_off(unidrv_switch_t* dev) { return unidrv_switch_to(dev, UNIDRV_SWITCH_OFF, 0, 0, 0); }
/// @brief 状态反转
inline static bool unidrv_switch_toggle(unidrv_switch_t* dev) { return unidrv_switch_to(dev, UNIDRV_SWITCH_TOGGLE, 0, 0, 0); }
/// @brief 取得当前状态
inline static unidrv_switch_state_t unidrv_switch_state(unidrv_switch_t* dev) { return dev ? dev->state : UNIDRV_SWITCH_OFF; }

/// @brief 闪一下
/// @param time: 保持时间, ms
void unidrv_switch_blink(unidrv_switch_t* dev, uint16_t time);

/// @brief 闪多下
/// @param onTime: 点亮时间, ms
/// @param offTime: 关闭时间, ms
/// @param count: 闪几次；=UNIOS_TASK_REPEAT_FOREVER 表示永远闪烁
/// @retval task, 可通过 osTaskKill() 来停止闪烁
unios_task_t unidrv_switch_blinkex(unidrv_switch_t* dev, uint16_t onTime, uint16_t offTime, uint16_t count);

/// @brief 停止闪烁
inline static void unidrv_switch_blink_stop(unidrv_switch_t* dev) { if(dev) unios_task_destroy(&dev->blinkTaskId); }
